﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using MrPP.Common;
using MrPP.UX;
using TMPro;
using UnityEngine;
using static MrPP.SerriedCabinet.CabinetGroup;

namespace MrPP.SerriedCabinet
{

    public class CheckView : CheckViewAbstract
    {

      //  [SerializeField]
      //  private CheckModel _model;

        [SerializeField]
        private Button _play;
        [SerializeField]
        private Button _stop;

        [SerializeField]
        private List<Button> _tabs;


        [SerializeField]
        TextMeshPro _waitCount;
        [SerializeField]
        TextMeshPro _checkCount;
        [SerializeField]
        TextMeshPro _otherCount;
        [SerializeField]
        private Book _book;

        public void Start()
        {
            /*
            _model.onState += doState;
            _model.onTab += doTab;
            // _model.onArchives += onArchives;
            _model.onItems += onItems;
            _model.onCheckPage += doPage;
            _model.onWaitPage += doPage;
            _model.onOtherPage += doPage;
            _model.onCheckList += onCheckList;
            Debug.LogError("###" + _model.getState());*/
            doState(_receiver.getState(), _receiver.getState());
            refresh();
        }

        private void doItems(ItemData[] obj)
        {
            refreshBook();
        }

        private void doCheckList(List<string> obj)
        {
            Debug.LogError(obj.Count);
            refreshBook();
        }
/*
        private void onArchives(ArchivesData[] obj)
        {
            refreshBook();
        }
        */
    
     

        private void refreshBook()
        {
            List<string> datas = null;
            int page = 0;
            var handler = new Handler(this._receiver);

            int wait = handler.getLength(Handler.Type.Wait);
            int check = handler.getLength(Handler.Type.Check);
            int other = handler.getLength(Handler.Type.Other);
            _waitCount.text = wait.ToString();
            _checkCount.text = check.ToString();
            _otherCount.text = other.ToString();

            switch (this._receiver.getTab())
            {
                case 0:
//                    Debug.LogError(":wait");
                    page = _receiver.getWaitPage();
                    datas = handler.getList(Handler.Type.Wait);
                 //   _book.max = Math.Max(0, (wait - 1) / _book.count + 1);
                    break;
                case 1:
               //     Debug.LogError(":check");
                    page = _receiver.getCheckPage();
                    datas = handler.getList(Handler.Type.Check);
                   // _book.max = Math.Max(0, (check - 1) / _book.count + 1);
                    break;
                case 2:
                //    Debug.LogError(":other");
                    page = _receiver.getOtherPage();
                    datas = handler.getList(Handler.Type.Other);
                   // _book.max = Math.Max(0, (other- 1) / _book.count + 1);
                    break;

            }

            _book.page = page;
          //  _book.max = Math.Max(0, (datas.Count-1)/_book.count +1);
            _book.setItems(datas);
            _book.refresh();
           
        }

        private void doPage(int arg1, int arg2)
        {
            refreshBook();
        }

       

        private void doTab(int last, int next)
        {
            _tabs[last].state = Button.State.Enabled;
            _tabs[next].state = Button.State.Selected;

            _tabs[last].refresh();
            _tabs[next].refresh();

            refreshBook();
        }

        private void refresh() {


           // _play.state = Button.State.Enabled;
            //_play.refresh();
           // _stop.state = Button.State.Disable;
           // _stop.refresh();
            int tab = _receiver.getTab();
            for (int i = 0; i < _tabs.Count; ++i) {
                if (tab == i)
                {
                    _tabs[i].state = Button.State.Selected;
                }
                else {

                    _tabs[i].state = Button.State.Enabled;
                }
                _tabs[i].refresh();
            }

            refreshBook();
           
        }
        /*
        private void doState(State arg1, State arg2)
        {
            if (arg2 == State.Running)
            {
                QRCodeManager.Instance.open();
            }
            else
            {
                QRCodeManager.Instance.close();
            }
        }*/

        private void doState(CheckPost.State last, CheckPost.State next)
        {
            if(next == CheckPost.State.Loading)
            {
                QRCodeManager.Instance.close();
                _play.state = Button.State.Disable;
                _stop.state = Button.State.Disable;
            }
            else if(next == CheckPost.State.Running)
            {
                QRCodeManager.Instance.open();
                _play.state = Button.State.Disable;
                _stop.state = Button.State.Enabled;
            }else if(next == CheckPost.State.Close)
            {
                QRCodeManager.Instance.close();
                _play.state = Button.State.Enabled;
                _stop.state = Button.State.Disable;
            }

            _play.refresh();
            _stop.refresh();
        }

        public override void onTab(int oldValue, int newValue)
        {
            this.doTab(oldValue, newValue);
        }

        public override void onPage(int oldValue, int newValue)
        {
            this.doPage(oldValue, newValue);
        }

        public override void onState(CheckPost.State oldValue, CheckPost.State newValue)
        {
            this.doState(oldValue, newValue);
        }

        public override void onItems(ItemData[] items)
        {
            doItems(items);
        }

        public override void onWaitPage(int oldValue, int newValue)
        {
            doPage(oldValue, newValue);
        }

        public override void onCheckPage(int oldValue, int newValue)
        {
            doPage(oldValue, newValue);
        }

        public override void onOtherPage(int oldValue, int newValue)
        {
            doPage(oldValue, newValue);
        }

        public override void onCheckList(List<string> list)
        {
            doCheckList(list);
        }

        private class Handler
        {

            private List<string> wait_;
            private List<string> check_;
            private List<string> other_;

            public Handler(ICheckReceiver receiver)
            {
                var items = receiver.getItems();
                List<string> check = receiver.getCheckList();
                List<string> list = new List<string>();
                Dictionary<string, ItemData> table = new Dictionary<string, ItemData>();
                foreach (var item in items) {
                    list.Add(item.sn);
                    table.Add(item.sn, item);
                }

                List<string> jiao = check.Intersect(list).ToList();
//                Debug.LogError("jiao:"+jiao.Count);
                List<string> wait = list.Except(check).ToList();
                List<string> other = check.Except(list).ToList();

                check_ = new List<string>();
                foreach (var j in jiao) {
                    check_.Add(table[j].text);
                }
                wait_ = new List<string>();
                foreach (var j in wait) {
                    wait_.Add(table[j].text);
                }

                other_ = other;

            }

            public enum Type {
                Wait,
                Check,
                Other,

            }




            public int getLength(Type type)
            {

                var list = this.getList(type);
                return list.Count;
            }
            /*
            public List<string> getList(Type type, int page, int count)
            {
                List<string> list = getList(type);
                if (page * count > list.Count)
                {
                    return new List<string>();
                }
                else if ((page + 1) * count > list.Count)
                {
                    return list.GetRange(page * count, list.Count - page * count);
                }
                else {

                    return list.GetRange(page * count, count);
                }
              //  return list;
            }
            */
            public List<string> getList(Type type)
            {
                switch (type) {
                    case Type.Wait:

                        return wait_;
                    case Type.Check:
                        return check_;
                    case Type.Other:
                        return other_;
                }
                throw new NotImplementedException();
            }
        }
    }
}